using System;
using Bases;
using Configs;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.UI;
using Random = UnityEngine.Random;

namespace Modules.Game.Enemies
{
    public class Enemy : MonoBehaviourSimplify
    {
        private static readonly int AnimSpeed = Animator.StringToHash("speed");

        public NavMeshAgent agent;
        public Animator anim;
        public Slider hpSlider;

        /// <summary>
        ///     怪物数据
        /// </summary>
        private EnemyData _data;

        private bool _isAttachHero;

        private bool _isSkilling;

        private float _time;

        public Action ReleaseAction;

        private void Awake()
        {
            agent.speed = 5.0f;

            ResetData();
        }

        private void Update()
        {
            if (!GameModel.Instance.IsGaming) return;

            if (!gameObject.activeSelf) return;

            Move();
            UpdateSecond();
        }

        private void OnCollisionEnter(Collision collision)
        {
            if (collision.collider.CompareTag("Player")) _isAttachHero = true;
        }

        private void OnCollisionExit(Collision collision)
        {
            if (collision.collider.CompareTag("Player")) _isAttachHero = false;
        }

        private void OnTriggerEnter(Collider other)
        {
            if (other.CompareTag("PlayerSkill"))
            {
                _isSkilling = true;
                AtkHero();
            }
        }

        private void OnTriggerExit(Collider other)
        {
            if (other.CompareTag("PlayerSkill")) _isSkilling = false;
        }

        protected override void OnBeforeDestroy()
        {
        }

        private void UpdateSecond()
        {
            _time += Time.deltaTime;
            if (_time < 1.0f)
                return;

            _time = 0.0f;
            UpdateHp();
            AtkHero();
        }

        private void Move()
        {
            agent.SetDestination(GameModule.Instance.GetHeroPos());

            anim.SetFloat(AnimSpeed, agent.velocity.magnitude);
        }

        private void UpdateHp()
        {
            if (_data.Attr.CurHp < _data.Attr.TotalHp) _data.Attr.CurHp++;

            hpSlider.value = _data.Attr.CurHp / _data.Attr.TotalHp;
        }

        /// <summary>
        ///     攻击英雄
        /// </summary>
        private void AtkHero()
        {
            if (!_isAttachHero) return;

            GameModule.Instance.OnHeroHit(_data);
        }

        public EnemyData GetData()
        {
            return _data;
        }

        public void ResetData()
        {
            _data = EnemyConfig.EnemyDatas[EnemyConfig.EnemyKeyDefault];
            _isAttachHero = false;
            _isSkilling = false;

            var duration = Random.Range(0, 360);
            var distance = Random.Range(0, 45);
            transform.position = new Vector3((float) Math.Cos(duration) * distance, 2,
                (float) Math.Sin(duration) * distance);

            UpdateHp();
        }

        public void CheckSkillHit(Vector3 heroPos, SkillData data)
        {
            if (!_isSkilling) return;

            // 扣减血量 = 技能伤害值 - 怪物防守值
            if (data.Attr.Atk <= _data.Attr.Def) return;

            _data.Attr.CurHp -= data.Attr.Atk - _data.Attr.Def;
            UpdateHp();

            // 血量小于0，回收
            if (_data.Attr.CurHp <= 0) ReleaseAction?.Invoke();
        }
    }
}